package io.zjw.testblelib;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.vmove.report100.Report100;
import com.vmove.signalproc.SignalProc;
import com.yuanxu.ecg.ECGManager;
import com.yuanxu.ecg.L;
import com.yuanxu.ecg.bean.UserInfo;
import com.yuanxu.ecg.callback.BaseCallback;
import com.yuanxu.ecg.callback.DeviceStatusCallback;
import com.yuanxu.ecg.callback.ExecuteCallback;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;

import cn.jesse.nativelogger.NLogger;
import io.mega.megablelib.MegaBleClient;
import io.zjw.testblelib.util.FileUtil;
import io.zjw.testblelib.util.HttpUtil;
import io.zjw.testblelib.util.UploadUtil;
import io.zjw.testblelib.view.EcgView;

public class EcgActivity extends AppCompatActivity {

    private static final String TAG = "EcgActivity";
    private static final int EVENT_SERVICE_CONNECT = 0;
    private static final int EVENT_SERVICE_CONNECT_LOSE = 1;
    private String MAC_OF_DEVICE = "";
    //int[] ecgData = new int[6];
    private boolean isWaiting = false;
    private byte[] bytes1 = new byte[20];
    private int sub;
    private SignalProc proc;
    private Report100 report100;
    private Dialog infoDialog = null;
    private String serverIP = null;
    int port = 8082;
    private MyClient myClient = null;
    private JSONArray jsonArray = null;
    private TextView macView;
    private TextView statusView;
    private TextView userView;
    private Button btnTest;
    private Button btnStop;
    private Button btn_bound;
    private TextView serverView;
    private String filePath = null;
    private FileWriter  writer = null;
    private FileWriter  writer2 = null;
    private FileWriter write3 = null;
    private String fileName = "";
    private int onProcess =0;
    private String phoneNumber;
    private String userName;
    private String ID;
    //环境配置，当env=ZB时，需自动上传文件
    private String env;
    private final Timer timer = new Timer();
    private final Timer timer2 = new Timer();
    private final Timer timer_zb_status = new Timer();

    private final Timer timer_battery = new Timer();
    private FileOutputStream fos ;
    private int testTime = 0 ;
    private StatusThread statusThread= null;
    //禁止退出
    private boolean banBack = false;
    //测试状态  初始化状态位正在准备测试
    private String status = "准备测试阶段";
    private EcgView ecgView;
    Thread fileUploadThread = null;
    Thread sendData = null;
    //设备连接状态
    boolean connectionStatus = false;

    long from = 0;

    DeviceStatusCallback deviceStatusCallback;

    private TextView batteryView ;
    ECGManager manager= null;
    //byte 数组数据 byte源数据
    private volatile ConcurrentLinkedQueue<byte[]> bytesDatas = new ConcurrentLinkedQueue<byte[]>();
    //byte to integer byte转integer
    private volatile ConcurrentLinkedQueue<int[]> ecgDatas = new ConcurrentLinkedQueue<int[]>();
    //integer to integer 滤波后的数据
    private volatile ConcurrentLinkedQueue<int[]> vDatas = new ConcurrentLinkedQueue<int[]>();

//    新版ecg图表，解决扫描绑定设备卡死退出的问题

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_e_c_g);
        manager = ECGManager
                .getInstance()
                .setLog(true, "ECG")
                .setAutoReconnect(true)
                .init(getApplication());

        if(deviceStatusCallback == null){
            deviceStatusCallback = new DeviceStatusCallback() {
                @Override
                public void onDeviceStatus(String deviceStatus) {
                    Log.w(TAG, "onDeviceStatus===="+deviceStatus);
                    String batteryStr = deviceStatus.substring(deviceStatus.length()-4);
                    float battery = (Integer.parseInt(batteryStr.substring(0,2),16)*256F+Integer.parseInt(batteryStr.substring(2),16))/10;
                    Log.i(TAG, "battery==="+battery);
                    int batt = (int) ((battery-3300)/10);
//                    if (batt == 0) batt = 1;
                    Log.i(TAG, "battDouble---"+batt);
                    batteryView.setText( "  电量:"+batt+"%");
                }

                @Override
                public void onFailure(int failCode, String info) {
                    Log.e(TAG, "onFailure==="+failCode+"====="+info);
                }
            };
        }
        filePath = this.getApplicationContext().getFilesDir().getPath()+"/ecg/";
        serverIP =  getIntent().getStringExtra("serverIP");
        phoneNumber = getIntent().getStringExtra("phoneNumber");
        userName = getIntent().getStringExtra("userName");
        ID = getIntent().getStringExtra("ID");
        env = getIntent().getStringExtra("env");
        String url = "ws://"+ serverIP+":54378/ws";
        try {
            myClient = new  MyClient(url);
            myClient.connectBlocking();
        } catch (Exception e) {
            e.printStackTrace();
            NLogger.e("ECG",e.getMessage());
        }
        proc = new SignalProc();
        proc.Init(100);
        ecgView = findViewById(R.id.ecgView);
        batteryView = findViewById(R.id.batteryView);
//        batteryView.setText("电量：--");
        statusView = findViewById(R.id.statusView);
        macView = findViewById(R.id.macView);
        btnTest = findViewById(R.id.btn_test);
        if(env.equals("ZB")){
            MAC_OF_DEVICE = this.getSharedPreferences("save.himi",Context.MODE_PRIVATE).getString("DEVICE_MAC","");
            if(MAC_OF_DEVICE.length()>0){
                Message message = new Message();
                message.what=1111;
                message.obj= MAC_OF_DEVICE;
                handler.sendMessage(message);
                btnTest.setEnabled(true);
                Toast.makeText(this,"绑定完成"+MAC_OF_DEVICE,Toast.LENGTH_SHORT).show();
            }
        }
        if(env.equals("TEST")){
            MAC_OF_DEVICE = this.getSharedPreferences("save.himi",Context.MODE_PRIVATE).getString("DEVICE_MAC","");
        }
        userView = findViewById(R.id.userView);
        userView.setText(phoneNumber);
        serverView = findViewById(R.id.serverView);

        btnStop = findViewById(R.id.tv_stop);
        btn_bound = findViewById(R.id.btn_bound);
        //检测服务状态
        //创建一个线程
        new Thread(() -> {

            //延迟两秒
            try {
                Thread.sleep( 1000 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            runOnUiThread(() -> {
                TimerTask testTimeLong = new TimerTask() {
                    @Override
                    public void run() {
                        serviceCheck();
                    }
                };
                timer.schedule(testTimeLong,1000,10000);

            });

        }).start();

    }

    /**
     * 获取本机Wifi MAC
     * @return
     */
    private String getLocalMac() {
        try {
            ArrayList<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if(!nif.getName().equalsIgnoreCase("wlan0")){
                    continue;
                }
                byte[] macBytes = nif.getHardwareAddress();
                if (macBytes == null) return "";
                StringBuilder res1 = new StringBuilder();
                for (Byte b : macBytes) {
                    res1.append(String.format("%02X:", b));
                }
                if (!TextUtils.isEmpty(res1)) {
                    res1.deleteCharAt(res1.length() - 1);
                }
                return res1.toString();
            }
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }

        return "";
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(banBack){
            if(keyCode == KeyEvent.KEYCODE_BACK){
                Toast.makeText(EcgActivity.this, status, Toast.LENGTH_SHORT).show();
                return true;
            }

        }
        return super.onKeyDown(keyCode, event);
    }

    public void serviceCheck(){
        int port = 8082;
        if(env.equals("ZB")){
            port = 8081;
        } else if (env.equals("ccy")) {
            port = 8109;
        }
        boolean result = ServerUtil.isPortUseful2(serverIP, port, 5000,env);
        if ( result){
            handler.sendEmptyMessage(EVENT_SERVICE_CONNECT);
        }else{
            handler.sendEmptyMessage(EVENT_SERVICE_CONNECT_LOSE);
        }
    }
    public void showInfo(View view) {
        PackageManager packageManager = getPackageManager();
        try {
            String versionName = packageManager.getPackageInfo(this.getPackageName(),0).versionName;
            String message = String.format(getString(R.string.info_content), versionName, MegaBleClient.megaParseVesrion(), serverIP);
            infoDialog = new AlertDialog.Builder(EcgActivity.this)
                    .setTitle(R.string.info_title)
                    .setPositiveButton(R.string.ok, null)
                    .setMessage(message)
                    .create();
            infoDialog.show();
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 点击开始测试的响应
    @RequiresApi(api = Build.VERSION_CODES.O)
    public void ecgExec(View view) throws JSONException, InterruptedException {
        //发送用户信息
        JSONObject jsonObject  = new JSONObject();
        jsonObject.put("useName",userName);
        jsonObject.put("ID",ID);
        jsonObject.put("phone",phoneNumber);
        sendData(jsonObject,"ECG-USER");
        Thread.sleep(500);
        startEcg();
    }

    public void startEcg() {
        banBack = true;
        status = "正在测试阶段，不允许退出";
        // 申请设备位置权限
        if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
            return;
        }

        // 检查设备是否开启定位
        LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        boolean gpsEnabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (!gpsEnabled) {
            Toast.makeText(this, "GPS disabled, plz enable", Toast.LENGTH_SHORT).show();
            return;
        }

        // 检查设备是否支持蓝牙
        BluetoothManager bleManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (bleManager == null) {
            Toast.makeText(this, "ble not support", Toast.LENGTH_SHORT).show();
            return;
        }

        // 检查蓝牙是否开启
        boolean bleEnabled = bleManager.getAdapter().isEnabled();
        if (!bleEnabled) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, 1);
            return;
        }

        //启用停止按钮
//        if(env.equals("ZB"))
        btnStop.setEnabled(true);
        btnTest.setEnabled(false);
        btn_bound.setEnabled(false);

        ECGManager
                .getInstance()
                .setLog(true, "ECG")
                .setAutoReconnect(true)
                .init(getApplication());
        if(MAC_OF_DEVICE==null || MAC_OF_DEVICE.trim().length()<1){
            infoDialog = new AlertDialog.Builder(EcgActivity.this)
                    .setTitle("错误：")
                    .setPositiveButton(R.string.ok, null)
                    .setMessage("请先绑定设备")
                    .create();
            infoDialog.show();
            return;
        }

        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        fileName =  "心电-"+userName+"-"+phoneNumber+"-"+simpleDateFormat.format(date);
        write3 = FileUtil.recordByte(filePath+fileName+".txt");
        writer2 = FileUtil.recordByte(filePath+fileName+"-source.txt");
        fos = FileUtil.outputStream(filePath+fileName+".dat");
        UserInfo userInfo = new UserInfo(userName, false, 20, 170, 65);
//        ECGManager
//                .getInstance()
                manager.execute(MAC_OF_DEVICE, userInfo, new ExecuteCallback() {

                    @Override
                    public void onSuccess() {//本轮检测任务成功
                        L.e("onSuccess");
                    }

                    @Override
                    public void onFailure(int failCode, String info) {//本轮检测任务失败
                        switch (failCode) {
                            case BaseCallback.FAIL_BLUETOOTH_NOT_AVAILABLE: //蓝牙不可用
                                Log.e(TAG, "蓝牙不可用");
                                break;
                            case BaseCallback.FAIL_OTHER:  //其他原因
                                Log.e(TAG, "其他原因");
                                break;
                            case ExecuteCallback.FAIL_CONNECTION_ALREADY_ESTABLISHED://本机已连接到其他硬件设备
                                Log.e(TAG, "本机已连接到其他硬件设备");
                                break;
                            case ExecuteCallback.FAIL_CONNECTION_START_FAIL://连接未正常开始
                                Log.e(TAG, "连接未正常开始");
                                break;
                        }
                        L.e("onFailure---" + failCode + "     info=" + info);
                    }



                    @SuppressLint("ResourceType")
                    @Override
                    public void onProcess(int process, String info) {//检测任务进度
                        onProcess = process;
                        switch (process) {
                            /**
                             *连接进度
                             */
                            case PROCESS_CONNECT_START://连接开始
                                statusView.setText("连接开始");
                                break;
                            case PROCESS_CONNECT_FAIL://连接失败
                                connectionStatus = false;
                                statusView.setText("连接失败");
                                statusView.setTextColor(Color.parseColor(getString(R.color.black)));
                                break;
                            case PROCESS_CONNECTED://已连接
                                connectionStatus = true;
                                TimerTask batterySearch = new TimerTask() {
                                    @Override
                                    public void run() {
                                        if(connectionStatus){
                                            manager.queryDeviceStatus(deviceStatusCallback);
                                        }
                                    }
                                };
                                timer_battery.schedule(batterySearch, 500, 60000);
                                break;
                            case PROCESS_DATA_RECEIVING://正在接收硬件发回的心电数据
                                connectionStatus = true;
                                statusView.setText("已连接");
                                statusView.setTextColor(Color.parseColor(getString(R.color.green)));
                                break;
                            case PROCESS_DISCONNECTED://连接断开
                                statusView.setText("连接断开");
                                resetButtons();
                                connectionStatus = false;
                                break;

                            /**
                             * notify进度
                             */
                            case PROCESS_NOTIFY_START://开始notify
                                break;
                            case PROCESS_NOTIFY_SUCCESS://notify成功
                                break;
                            case PROCESS_NOTIFY_FAIL://notify失败
                                break;

                            /**
                             *  其他如指令收发、数据接收等进度
                             */
                            case PROCESS_CMD_SENDING://正在发送相关指令
                                if(from == 0){
                                    from = System.currentTimeMillis();
                                }
                                break;
                            case PROCESS_IDLE://任务结束（成功或失败），达到空闲状态
                                break;
                        }
                        L.d("onProcess---" + process + "     info=" + info);
                    }
                    @RequiresApi(api = Build.VERSION_CODES.O)
                    @Override
                    public void onReceivedOriginalData(byte[] data) {//原始心电数据
                        parseRealTimeData(data);
                        if (onProcess == PROCESS_DATA_RECEIVING) {
                            long to = System.currentTimeMillis();
                            int time = (int) (to-from)/1000;
                            Log.i(TAG, time +"==="+to+"==="+from);
                            String duration = String.format("%02d:%02d", time/60, time%60);
                            btnTest.setText(duration);
                        }
                    }
                });
        //创建一个线程 发送数据
        new Thread(() -> {

            runOnUiThread(() -> {
                TimerTask testTimeLong = new TimerTask() {
                    @RequiresApi(api = Build.VERSION_CODES.O)
                    @Override
                    public void run() {
                        try {
                            sendData();
                        } catch (IOException | InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                timer2.schedule(testTimeLong,500,500);
            });

        }).start();

        //ZB：创建一个线程，监测测试状态，如果测试结束则立刻停止
        if(env.equals("ZB")){
//            statusThread = new StatusThread();
//            statusThread.run();
            new Thread(() -> {

                runOnUiThread(() -> {
                    TimerTask status_task = new TimerTask() {
                        @RequiresApi(api = Build.VERSION_CODES.O)
                        @Override
                        public void run() {
                            String response = HttpUtil.httpGet("http://"+serverIP+":8081/push/status/"+phoneNumber);
//                            String response = HttpUtil.httpGet("http://192.168.248.5:8090/push/status/"+phoneNumber);
                            Log.i("response--",response);
                            try {
                                JSONObject jsonObject = new JSONObject(response);
//                                Log.i("code",jsonObject.getString("code"));
//                                Log.i("data",jsonObject.getString("data"));
                                if(jsonObject.getString("data").equals("2")){
//                                    btnStop.performClick();
                                    ecgStop(getWindow().getDecorView());
//                                    uploadFile();
                                    Thread.sleep(1000);
//                                    Thread.interrupted();
                                }
                            } catch (JSONException | InterruptedException | IOException e) {
                                e.printStackTrace();
                            }
                        }
                    };
                    timer_zb_status.schedule(status_task,500,1000);
                });

            }).start();
        }
    }


    // 点击绑定设备的响应
    public void ecgBound(View view){
        IntentIntegrator intentIntegrator = new IntentIntegrator(EcgActivity.this);
        intentIntegrator.initiateScan();
    }

    @Override
    // 处理申请权限的结果
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        L.d("req code:" + requestCode + " ret:" + grantResults);
        switch (requestCode) {
            case 1: {
                if (grantResults.length > 0) {
                    L.d("result: " + grantResults[0]);
                }
                if (grantResults.length > 0) {
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        startEcg();
                    } else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                        Toast.makeText(this, "您已拒绝app使用位置权限，无法连接设备", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

    //停止采集
    @RequiresApi(api = Build.VERSION_CODES.O)
    public void ecgStop(View view) throws IOException, JSONException, InterruptedException {
        timer2.cancel();
        timer_zb_status.cancel();
        Log.i("执行结束","执行结束");
//        ECGManager.getInstance().stop();
        ECGManager.getInstance().disconnect();
        Log.i("执行结束完成","执行结束完成");
//        timer_zb_status.cancel();
//        try {
//            ECGManager.getInstance().disconnect();


//                        ECGManager.getInstance().disconnect();
            Log.i("onProcess ", String.valueOf(onProcess));
            if(env.equals("ZB")){
                /*Timer timer = new Timer();
                TimerTask task = new TimerTask() {
                    @Override
                    public void run() {
                        if (onProcess == 300){
                            getResult();
                            timer.cancel();
                            onProcess = 0;
                        }
                    }
                };
                if (onProcess != 0 ){
                    timer.schedule(task,2000,1000);
                }*/
                getResult();
                boolean b = false;
                File fileResult = new File(filePath,fileName+"-result.txt");
                while(!b){
                    Log.i(new Date()+"flag--b",String.valueOf(b));
                    if(fileResult.exists()){
                        b = true;
//                        //发送心脏指标
//                        FileReader fr = new FileReader(fileResult);
//                        BufferedReader br = new BufferedReader(fr);
//                        String line;
//                        StringBuffer buffer = new StringBuffer();
//                        while((line = br.readLine()) != null){
//                            buffer.append(line);
//                        }
//                        JSONObject jsonObject = new JSONObject(buffer.toString()).getJSONObject("score");
//                        int totalScore = jsonObject.getInt("total_score");
//                        Log.i("发送TOTAL_SCORE",String.valueOf(totalScore));
//                        sendData(totalScore,"TOTAL_SCORE");
                        Thread.sleep(1000);
                    }
                }
                fileUploadThread = new FileUploadThread();
                fileUploadThread.start();
            }else{
                ECGManager.getInstance().disconnect();
                android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(EcgActivity.this);
//            android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(this.getApplicationContext());
                builder.setTitle("提示");
                builder.setMessage("点击上传按钮上传源数据文件");
                builder.setPositiveButton("上传", (dialog, which) -> {
                    Timer timer = new Timer();
                    TimerTask task = new TimerTask() {
                        @Override
                        public void run() {
                            Log.i("onProcess", String.valueOf(onProcess));
                            if (onProcess == 300){
                                getResult();
                                timer.cancel();
                                onProcess = 0;
                            }
                        }
                    };
                    if (onProcess != 0 ){
                        timer.schedule(task,2000,1000);
                    }
                    fileUploadThread = new FileUploadThread();
                    fileUploadThread.start();
                                resetButtons();
                });
                builder.setNeutralButton("取消", (dialog,which) ->{
                    banBack = false;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Intent intent = new Intent();
                    intent.setClass(EcgActivity.this,IndexActivity.class);
                    startActivity(intent);
                });
                builder.show();
            }
//
//        }catch (Exception e){

//            Log.e("stop",e.getMessage());
//        }




    }


    //解析数据
    @RequiresApi(api = Build.VERSION_CODES.O)
    public void getResult(){
        try {
            status = "分析测试数据，不允许退出";
            banBack = true;
            if(writer != null){
                writer.close();
            }
            if(writer2 != null){
                writer2.close();
            }
            if(write3 != null){
                write3.close();
            }
            report100 = new Report100();
            int result = report100.make(filePath+fileName+".dat",filePath+fileName+"-result.txt",1,0,"18888888",EcgActivity.this);

            /*if (result == 0){
                Map map = new HashMap();
                ByteBuffer byteBuffer = FileUtil.readFileByBytes(filePath+fileName+".dat");
                String resultJson = FileUtil.readFileContent(filePath+fileName+"-result.txt");
                map.put("byteBuffer",byteBuffer);
                map.put("resultJson",resultJson);
                map.put("name",fileName);
                sendData(map,"FILE");
                banBack = false;
            }*/
        }catch (Exception e){
            banBack = false;
            NLogger.e("FILE",e.getMessage());
        }

    }

    /**
     * 将采集到的实时数据 转换成 ecg Y轴的值
     * 并写入ecgView队列中
     * @param bytes
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public void parseRealTimeData(byte[] bytes) {
        try {
            int[] ecgData = new int[6];
            int i;
            if (bytes.length == 18) {
                //将byte数组放入队列
                bytesDatas.add(bytes);
                for (i = 0; i < 18; i += 3) {
                    ecgData[i / 3] = (bytes[i] & 255) << 16 | (bytes[i + 1] & 255) << 8 | bytes[i + 2] & 255;
                }
                //向ecg视图写入数据
                //EcgView.addEcgData0(getV(ecgData));
                //将未滤波的数据放入队列
                int [] vData = getV(ecgData);
                ecgView.addEcgData0(vData);

                //滤波前数据入队列
                ecgDatas.add(ecgData);
                //滤波后数据如队列
                vDatas.add(vData);

            } else {
                for (i = 0; i < bytes.length; ++i) {
                    bytes1[i] = bytes[i];
                }
                sub = bytes.length;
                isWaiting = true;
            }
            if (isWaiting) {
                for (i = sub; i < 18; ++i) {
                    bytes1[i] = bytes[i - sub];
                }
                for (i = 0; i < 18; i += 3) {
                    ecgData[i / 3] = (bytes1[i] & 255) << 16 | (bytes1[i + 1] & 255) << 8 | bytes1[i + 2] & 255;
                }
                bytesDatas.add(bytes1);
                //向ecg视图写入数据
                int[] value = getV(ecgData);
                ecgView.addEcgData0(value);
                ecgDatas.add(ecgData);
                vDatas.add(value);

                isWaiting = false;
            }
        } catch (Exception var6) {
            var6.printStackTrace();
        }
    }
    /**
     * 上传数据文件
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private String uploadFile() throws IOException, InterruptedException, JSONException {

        status = "上传测试结果阶段，不允许退出";
        banBack = true;
        Thread.sleep(1000);
        int port = 8082;
        if(env.equals("ZB")){
            port = 8081;
        } else if (env.equals("ccy")) {
            port = 8109;
        }
        String url = "http://"+ serverIP+":"+port+"/file/uploadData";
        Message msg = new Message();
        String result = "fail";
            msg.what = 1;
            msg.obj="开始上传文件";
            handler.sendMessage(msg);
            File fileSource = new File(filePath,fileName+".dat");
            boolean flagSource = true;
            int waitTimeSource = 0;
            while(flagSource){
                if(fileSource.exists()){
                    msg = Message.obtain();
                    result = UploadUtil.getInstance().upload(url,fileSource);
                    Thread.sleep(500);
                    if(result.equals("success")){
                        msg.obj="源文件"+fileSource.getName()+"上传完成";
                    }else{
                        msg.obj="源文件"+fileSource.getName()+"上传失败";
                    }
                    flagSource = false;
                    handler.sendMessage(msg);
                }else{
                    if(waitTimeSource < 10 ){
                        waitTimeSource += 1;
                        Thread.sleep(500);
                    }else{
                        flagSource = false;
                    }
                }
            }


        File fileResource2 = new File(filePath,fileName+".txt");
        boolean flagResource2 = true;
        int waitTimeResource2 = 0;
        while(flagResource2){
            if(fileResource2.exists()){
                msg = Message.obtain(handler);
                msg.obj="源数据文件："+fileResource2.getName();
                handler.sendMessage(msg);
                result = UploadUtil.getInstance().upload(url,fileResource2);
                Thread.sleep(500);
                msg = Message.obtain(handler);
                if(result.equals("success")){
                    msg.obj="源文件"+fileResource2.getName()+"上传完成";
                }else{
                    msg.obj="源文件"+fileResource2.getName()+"上传失败";
                }
                flagResource2 = false;
                handler.sendMessage(msg);
            }else{
                if(waitTimeResource2 < 10 ){
                    waitTimeResource2 += 1;
                    Thread.sleep(500);
                }else{
                    flagResource2 = false;
                }

            }
        }

        File fileResult = new File(filePath,fileName+"-result.txt");
               boolean flag = true;
        int waitTimeFlag = 0;
        while(flag){
            if(fileResult.exists()){
                //发送心脏指标
                FileReader fr = new FileReader(fileResult);
                BufferedReader br = new BufferedReader(fr);
                String line;
                StringBuffer buffer = new StringBuffer();
                while((line = br.readLine()) != null){
                    buffer.append(line);
                }
//                com.alibaba.fastjson.JSONObject score = com.alibaba.fastjson.JSONObject.parseObject(buffer.toString()).getJSONObject("score");
//                if(!env.equals("ZB")){
                    JSONObject jsonObject = new JSONObject(buffer.toString()).getJSONObject("score");
                    int totalScore = jsonObject.getInt("total_score");
                Log.i("ecg----","747");
                    sendData(totalScore,"TOTAL_SCORE");
//                }

                msg = Message.obtain(handler);
                msg.obj="开始上传结果文件："+fileResult.getName();
                handler.sendMessage(msg);
                result = UploadUtil.getInstance().upload(url,fileResult);
                Thread.sleep(500);
                msg = Message.obtain(handler);
                if(result.equals("success")){
                    msg.obj="结果文件"+fileResult.getName()+"上传完成";
                }else{
                    msg.obj="结果文件"+fileResult.getName()+"上传失败";
                }
                flag = false;
                handler.sendMessage(msg);
            }else{
                if(waitTimeFlag < 10 ){
                    waitTimeFlag += 1;
                    Thread.sleep(500);
                }else{
                    flag = false;
                }
            }
        }
        Thread.sleep(500);
        banBack = false;
        Message message = new Message();
        message.what = 200;
        message.obj = result;
        handler.sendMessage(message);
        return result;
    }

    /**
     * 计算Y轴的值
     * @param ecgData
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private int[] getV(int[] ecgData){
//        jsonArray = new JSONArray();
        int[] values = new int[ecgData.length];
        for (int i=0;i<ecgData.length;i++){
            int value= proc.Run(ecgData[i]);
//            Log.d(this.getClass().getName(), "原始值："+ecgData[i] + "；计算后的值："+value);
            values[i] = value;
//            jsonArray.put(value);
//            sendData(jsonArray,"ECG");
        }
        return values;
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void sendData() throws IOException, InterruptedException {
        //滤波后数据数据发送，写入文件
        if(!vDatas.isEmpty()){
            jsonArray = new JSONArray();
            for (int i = 0; i < vDatas.size(); i++) {
                int[] values = vDatas.poll();
                if(values != null){
                    for (int j = 0; j < values.length; j++) {
                        //将滤波后数据写入文件
                        write3.write(values[j]+",");
                        jsonArray.put(String.valueOf(values[j]));
                    }
                }
            }
            sendData(jsonArray,"ECG");
        }
        if(!ecgDatas.isEmpty()){
            JSONArray jsonArraySource = new JSONArray();
            for (int m =0 ;m<ecgDatas.size();m++){
                int [] values =ecgDatas.poll();
                if(values != null){
                    for (int i=0;i<values.length;i++){
                        writer2.write(values[i]+",");
                        jsonArraySource.put(String.valueOf(values[i]));
                    }
                }
            }
            sendData(jsonArraySource,"ECG_SOURCE");
        }

        for (int n =0 ;n<bytesDatas.size();n++){
            byte [] values =bytesDatas.poll();
            if(values != null){
                fos.write(values);
            }
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void sendData(Object values,String flag) {
        JSONObject dataJson = new  JSONObject();
        if (myClient == null){
            return;
        }
        if (myClient.isOpen()){
            try {
//                Log.i(TAG,flag);
                dataJson.put("flag",flag);
                dataJson.put("data",values);
                dataJson.put("date", LocalDateTime.now().toString());
                Log.i("sendDate",flag+"-----"+dataJson);

                myClient.send(dataJson.toString());
            }catch (Exception e){
                myClient.send(dataJson.toString());
                Log.i("sendDate",flag+"-----"+dataJson);
            }
        }else{
            String status = myClient.getReadyState().toString();
//            Log.d(TAG, "myClient: 通道异常"+ myClient.getReadyState().toString() );
            if (status.equals("CLOSING") || status.equals("CLOSED")) {
                myClient.reconnect();
            }
            if(myClient.isOpen()){
                myClient.send(dataJson.toString());
            }
        }
    }

    @Override
    protected void onDestroy() {
        timer.cancel();
        timer2.cancel();
        timer_zb_status.cancel();
        timer_battery.cancel();
        testTime = 0;
        connectionStatus = false;
        super.onDestroy();
        ECGManager.getInstance().stop();
        ECGManager.getInstance().disconnect();
        ECGManager.getInstance().release();
        if(fileUploadThread != null){
            fileUploadThread.interrupt();
        }
        if (myClient == null){
            return;
        }
        myClient.close();

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        //获取解析结果
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode,resultCode,data);
        if(result != null){
            if(result.getContents() == null){
                Toast.makeText(this,"取消扫描",Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(this,"开始绑定",Toast.LENGTH_SHORT).show();
                //TODO 正则 MAC 判断格式：(([a-f0-9]{2}:)|([a-f0-9]{2}-)){5}[a-f0-9]{2}
                String regex = "(([A-Fa-f0-9]{2}:)|([A-Fa-f0-9]{2}-)){5}[A-Fa-f0-9]{2}";
                String temp = result.getContents();
                if(temp.matches(regex)){
                    MAC_OF_DEVICE = result.getContents();
//                    if(env.equals("ZB")){
                        SharedPreferences setting = this.getSharedPreferences("save.himi",Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = setting.edit();
                        editor.putString("DEVICE_MAC",MAC_OF_DEVICE);
                        editor.commit();
//                    }
                    Message message = new Message();
                    message.what=1111;
                    message.obj= MAC_OF_DEVICE;
                    handler.sendMessage(message);
                    Toast.makeText(this,"绑定完成"+result.getContents(),Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(this,"设备异常"+result.getContents(),Toast.LENGTH_SHORT).show();
                }
                btnTest.setEnabled(true);
            }
        }else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    private Handler handler = new Handler(){
        @SuppressLint("ResourceType")
        public void handleMessage(Message msg) {
            if(msg.what == 1111){
                macView.setText(msg.obj.toString());
            }else if (msg.what == 200){
                banBack = false;
                AlertDialog.Builder builder;
                builder = new AlertDialog.Builder(EcgActivity.this);
                builder.setTitle("提示");
                builder.setMessage("源文件上传已完成");
//                builder.setPositiveButton("确定",null);
                builder.setPositiveButton("确定", (dialog, which) -> {
                    Timer timer = new Timer();
                    TimerTask task = new TimerTask() {
                        @Override
                        public void run() {
                            if(!banBack){
                                try {
                                    Thread.sleep(500);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                timer.cancel();
                                Intent intent = new Intent();
                                intent.setClass(EcgActivity.this,IndexActivity.class);
                                startActivity(intent);
                            }
                        }
                    };
                    timer.schedule(task,100,500);
                });
                builder.show();

            }else if(msg.what == EVENT_SERVICE_CONNECT){
                serverView.setText("已连接");
                serverView.setTextColor(Color.parseColor(getString(R.color.green)));
            }else if(msg.what == EVENT_SERVICE_CONNECT_LOSE){
                serverView.setText("未连接");
                serverView.setTextColor(Color.parseColor(getString(R.color.black)));
            }else {
                Toast toast = Toast.makeText(getApplicationContext(),String.valueOf(msg.obj),Toast.LENGTH_SHORT);
                toast.show();
            }

        }
    };

    private void resetButtons() {
        btnTest.setText("开始测试");
        btn_bound.setEnabled(true);
        btnTest.setEnabled(true);
        btnStop.setEnabled(false);
    }


    class FileUploadThread extends Thread{
        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void run() {
            try {
                uploadFile();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    //ZB 任务监测线程
    class StatusThread extends Thread{
        @Override
        public void run() {
            while(true){
                String response = HttpUtil.httpGet("http://"+serverIP+":8081/push/status/"+phoneNumber);
//                        String response = HttpUtil.httpGet("http://"+serverIP+":8081/push/status/"+phoneNumber);
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    if(jsonObject.getString("data").equals("2")){
                        Thread.sleep(2000);
                        btnStop.performClick();
                        Thread.sleep(500);
                        this.interrupt();
                    }else{
                        Thread.sleep(1000);
                    }
                } catch (JSONException | InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

